/*
Hermes Core: General Purpose Mobile Agent Platform
Copyright (C) 2006 UNICAM - Università degli Studi di Camerino

Group leaders: Flavio Corradini and Emanuela Merelli

Developers: Ezio Bartocci, Diego Bonura, Rosario Culmone,
Davide Lorenzoli, Leonardo Mariani, Francesca Piersigilli, 
Lorenzo Scortichini, Leonardo Vito.

GNU Lesser Public License

This library is free software; you can redistribute it 
and/or modify it under the terms of the GNU Lesser General 
Public License as published by the Free Software Foundation, 
version 2.1 of the License.

This library is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
See the GNU Library General Public License for more details.

You should have received a copy of the GNU Library General Public 
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.

Emanuela Merelli
Dipartimento di Matematica ed Informatica
Università di Camerino
via Madonna delle Carceri, 62032 Camerino, Italy
E.Mail: emanuela.merelli@unicam.it
*/
package hermesV2.agent;

import hermesV2.util.HermesLogger;

import java.util.Properties;


/**
 * ServiceAgent class represents an agent that offers services to user agents
 * or other service agent. It exdends the features implemented in the general
 * agent class plus it offers a way to manage the discovery component of the
 * basic services layer.
 *
 * @author Diego Bonura
 */
public abstract class ServiceAgent extends Agent {
    /**
	 * 
	 */
	private static final long serialVersionUID = 7824021015524128642L;
	/**
     * The properties of the current place.
    */
    private Properties properties;

    /**
     * It creates a service agents giving the name.
     *
     * @param ServiceAgentName The name of the service agent.
     */
    public ServiceAgent(String ServiceAgentName) {
        super(ServiceAgentName);
    }

    /**
     * Sets the properties of the current place.
     *
     * @param properties The properties of the current place.
     */
    final public void setPlaceProperties(Properties properties) {
        this.properties = properties;
    }

    /**
     * Returns the properties of the current place.
     *
     * @return The properties of the current place.
     */
    final public Properties getPlaceProperties() {
        return properties;
    }

    /**
     * It is usefull when a services wants to be visible into the place. This
     * method interfaces the discovery component of the basic services layer
     * and it adds the service agent identificator plus a keyword to
     * identificate it into the place.
     *
     * @param keyWord A key word usefull to identificate the service agent.
     */
    final public void registerService(String keyWord) {
        String[] keyWords = new String[1];
        keyWords[0] = keyWord;
        registerService(keyWords);
    }
    
    /**
     * It is usefull when a services wants to be visible into the place and to propagate the
     * registration on the network.
     * This method interfaces the discovery component of the basic services layer
     * and it adds the service agent identificator plus a keyword to
     * identificate it into the place.
     *
     * @param keyWord A key word usefull to identificate the service agent.
     * @param propagate True if the registration should be sent remotelly false otherwise.
     */
    final public void registerService(String keyWord, boolean propagate) {
        String[] keyWords = new String[1];
        keyWords[0] = keyWord;
        registerService(keyWords,propagate);
    }
    
    /**
     * It is usefull when a services wants to be visible into the place and to propagate the
     * registration on the network.
     * This method interfaces the discovery component of the basic services layer
     * and it adds the service agent identificator plus a keyword to
     * identificate it into the place.
     *
     * @param keyWordsArray An array of key words usefull to identificate the
     *        serviec agent.
     * @param propagate True if the registration should be sent remotelly false otherwise.
     */
    final public void registerService(String[] keyWordsArray, boolean propagate) {
        if (basicServices.getUpdateInterface() != null) {
            basicServices.getUpdateInterface().setService(this.getIdentificator(), keyWordsArray,propagate);
        } else {
            HermesLogger.log(HermesLogger.WARNING, "No Discovery interface found!");
        }
    }

    /**
     * It is usefull when a services wants to be visible into the place. This
     * method interfaces the discovery component of the basic services layer
     * and it adds the service agent identificator plus an array of keywords
     * to identificate it into the place.
     *
     * @param keyWordsArray An array of key words usefull to identificate the
     *        serviec agent.
     */
    final public void registerService(String[] keyWordsArray) {
        if (basicServices.getUpdateInterface() != null) {
            basicServices.getUpdateInterface().setService(this.getIdentificator(), keyWordsArray,false);
        } else {
            HermesLogger.log(HermesLogger.WARNING, "No Discovery interface found!");
        }
    }
    
    /**
     * Sets the protocol of a  service agent into the component.
     *
     * @param protocol The protocol of the services.
     */
    final public void registerProtocol(AbstractProtocol protocol){
        if (basicServices.getUpdateInterface() != null) {
            basicServices.getUpdateInterface().setServiceProtocol(this.getIdentificator(), protocol);
        } else {
            HermesLogger.log(HermesLogger.WARNING, "No Discovery interface found!");
        }
    }


    /**
     * Registers the current service agent to the secuity component, to protect it self from unallowed agents.
     *
     * @param userId The string of the user name.
     * @param passwd The password.
     */
    final public void registerToSecurityManager(String userId, String passwd) {
        if (basicServices.getSecurityInterface() != null) {
            if (this.getIdentificator().isServiceAgent()) {
                basicServices.getSecurityInterface().registerServiceAgent(this.getIdentificator(), userId, passwd);
            } else {
                HermesLogger.log(HermesLogger.WARNING, "The agent: " + this.getIdentificator() + " is not a serviceAgent!");
            }
        } else {
            HermesLogger.log(HermesLogger.WARNING, "No Security interface found!");
        }
    }

    /**
     * Delete the registration from the security component, the service agent will receive all messages
     *
     * @return true if the registration is deleted otherwise false.
     */
    final public boolean unregisterToSecurityManager() {
        boolean success;
    	if (basicServices.getSecurityInterface() != null) {
            if (this.getIdentificator().isServiceAgent()) {
                success= basicServices.getSecurityInterface().unregisterServiceAgent(this.getIdentificator());
            } else {
                HermesLogger.log(HermesLogger.WARNING, "The agent: " + this.getIdentificator() + " is not a serviceAgent!");
                success = false;
            }
        } else {
            HermesLogger.log(HermesLogger.WARNING, "No Security interface found!");
            success= false;
        }
    	return success;
    }
}
